//
//  MTBLEDevice.swift
//  Clock
//
//  Created by 方强 on 16/7/1.
//  Copyright © 2016年 MT. All rights reserved.
//

import UIKit
import CoreBluetooth

public class MTBLEDevice {
    
    // 设备类型
    private var devicetype = MTBLEDevice_MTBLEDEVICETYPE.BLE; // 设备类型

    private var refreshtime:Double = 0.0;
    
    // BLE标准参数
    private var peripheral: CBPeripheral!;  // 设备信息
    private var currentRssi:Int = 0; // 当前rssi值
    private var advertisementData:[String : Any]!;  // 广播数据
    private var connectAble = true;
    
    private var avgRssi:Int = 0;  // 平均rssi
    
    // IBeacon参数
    private var major = 0;
    private var minor = 0;
    
    // MTBLE和附加参数
    private var mac:String?; // MAC地址
    private var battery:Int = 0; // 电池电量
    private var setlev = 0; // 部署等级
    private var beaconid = 0;  // 当前广播beacon的id
    
    // 馒头模块参数
    private var userDatas:Data?;  // 用户自定义参数
    
    // 转发器参数
    private var classConnect = false;
    
    public init(peripheral: CBPeripheral!, advertisementData: [String : Any], rssi: Int) {
//        super.init();
        self.reflashInf(peripheral: peripheral, advertisementData: advertisementData, rssi: rssi);
    }
    
    public func reflashInf(peripheral: CBPeripheral!, advertisementData: [String : Any], rssi: Int){
        
        let date = NSDate();
        self.refreshtime = date.timeIntervalSince1970;  // 更新当前时间戳
        
        self.peripheral = peripheral;
        self.advertisementData = advertisementData;
        if let value = advertisementData[CBAdvertisementDataIsConnectable] as? Bool{   // 解析是否可连接
            self.connectAble = value;
        }else{
            self.connectAble = true;
        }
        reflashRssi(rssi: rssi);

        self.devicetype = MTBLEDevice.analysisType(advertisementData: self.advertisementData);
        
        if(self.devicetype == MTBLEDevice_MTBLEDEVICETYPE.MTBeacon3){
            analysisMTBeacon3();
            return;
        }
        
        if(self.devicetype == MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4){
            analysisMTBeacon4();
            return;
        }
        
        if(self.devicetype == MTBLEDevice_MTBLEDEVICETYPE.MTBLE){
            analysisMTBLE();
            return;
        }
        
    }
    
    public func reflashInf(device:MTBLEDevice!){
        self.reflashInf(peripheral: device.getDevice(), advertisementData: device.getScanRecord(), rssi: device.getCurrentRssi());
    }
    
    public func getDevice() -> CBPeripheral!{
        return peripheral;
    }
    public func getScanRecord() -> [String : Any]!{
        return advertisementData;
    }
    public func getCurrentRssi() -> Int{
//        let date = NSDate();
//        if(date.timeIntervalSince1970 > (self.refreshtime+5)){
//            currentRssi = -200;
//        }
        return currentRssi;
    }
    public func getAvgRssi() -> Int{
//        let date = NSDate();
//        if(date.timeIntervalSince1970 > (self.refreshtime+5)){
//            avgRssi = -200;
//        }
        
        return avgRssi;
    }
    public func getMac() -> String?{
        return mac;
    }
    public func getBattery() -> Int{
        return battery;
    }
    public func getDevicetype() -> MTBLEDevice_MTBLEDEVICETYPE{
        return devicetype;
    }
    public func getMajor() -> Int{
        return self.major;
    }
    public func getMinor() -> Int{
        return minor;
    }
    public func getSetlev() -> Int{
        return self.setlev;
    }
    public func isConnectAble() -> Bool{
        return self.connectAble;
    }
    public func getUserDatas() -> Data?{
        return userDatas;
    }

    
    public func isClassConnect() -> Bool{
        return classConnect;
    }
    
    private static let setLvName = ["可连接","密码连接","临时部署","永久部署"];
    public static func getSetLvName(index:Int) -> String?{
        
        if(index>(setLvName.count-1)){
            return "未知属性";
        }
        
        return setLvName[index];
    }
    
    private func reflashRssi(rssi:Int) {
        self.currentRssi = rssi;
        if (self.avgRssi == 0) {
            self.avgRssi = rssi;
        } else {
            self.avgRssi = (self.avgRssi + self.currentRssi) / 2;
        }
    }
    // 判断设备类型
    private static func analysisType(advertisementData: [String : Any]) -> MTBLEDevice_MTBLEDEVICETYPE{
        var uuid = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID];
        if((uuid != nil) && (uuid?.count == 1)){
            let uuidbyte = MTBLEDevice.CBUUIDToByte(uuid: uuid![0]);
            
            if(uuidbyte.count != 16){
                return MTBLEDevice_MTBLEDEVICETYPE.BLE;
            }
            
            var lrc:UInt8 = 0;
            for i in uuidbyte {
                lrc = lrc &+ i;
            }
            
            if(lrc != 0){
                return MTBLEDevice_MTBLEDEVICETYPE.BLE;
            }
            
            if(uuidbyte[0] == 0x10){
                switch(uuidbyte[1]){
                case 0x01: return MTBLEDevice_MTBLEDEVICETYPE.MTBLE;
                case 0x02: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon3;
                case 0x03: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon3;
                case 0x04: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                case 0x05: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                case 0x06: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                case 0x07: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                case 0x08: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                case 0x09: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                case 0x0A: return MTBLEDevice_MTBLEDEVICETYPE.MTBeacon4;
                default: break;
                }
                return MTBLEDevice_MTBLEDEVICETYPE.MTBLE;
            }
            return MTBLEDevice_MTBLEDEVICETYPE.MTBLE;
        }
        
        let nsdata = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data;
        if(nsdata != nil){
            let value = MTTools.converDataToByteArray(data: nsdata!);
            if (value.count == 29) {
                var lrc:UInt8 = 0;
                for i in 0 ..< 20 {
                    lrc = lrc &+ value[i];
                }
                if (lrc != 0) {
                    return MTBLEDevice_MTBLEDEVICETYPE.BLE;
                }
                if (value[0] == 0x10) {
                    switch (value[1]) {
                    case 0x10:
                        return MTBLEDevice_MTBLEDEVICETYPE.MTWX;
                    default:
                        break;
                    }
                    return MTBLEDevice_MTBLEDEVICETYPE.BLE;
                }
                return MTBLEDevice_MTBLEDEVICETYPE.BLE;
            }
        }
        
        return MTBLEDevice_MTBLEDEVICETYPE.BLE;
    }

    // 分析MTBLE参数
    private func analysisMTBLE(){
        let uuid = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID];
        if((uuid == nil) || (uuid?.count != 1)){
            return;
        }
        let value = MTBLEDevice.CBUUIDToByte(uuid: uuid![0]);
        if(value.count != 16){
            return;
        }
        self.mac = String(format: "%02X:%02X:%02X:%02X:%02X:%02X", value[9], value[10], value[11], value[12], value[13], value[14]);
        self.battery = MTTools.convertUint8(b: value[2]);
        
        self.userDatas = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data;
    }
    
    // 分析MTBeacon3参数
    private func analysisMTBeacon3(){
        
        let uuid = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID];
        if((uuid == nil) || (uuid?.count != 1)){
            return;
        }
        let value = MTBLEDevice.CBUUIDToByte(uuid: uuid![0]);
        
        if(value.count != 16){
            return;
        }
    
        self.battery = MTTools.convertUint8(b: value[2]);
        self.setlev = Int(value[8]) - 0x41;

        self.major = MTTools.convertUint16(hb: value[4], lb: value[5]);
        self.minor = MTTools.convertUint16(hb: value[6], lb: value[7]);
        
        self.mac = String(NSString(format: "%02X:%02X:%02X:%02X:%02X:%02X", value[9], value[10], value[11], value[12], value[13], value[14]));
    }
    
    // 分析MTBeacon4参数
    private func analysisMTBeacon4(){
        let uuid = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID];
        if((uuid == nil) || (uuid?.count != 1)){
            return ;
        }
        let value = MTBLEDevice.CBUUIDToByte(uuid: uuid![0]);
        
        if(value.count != 16){
            return ;
        }
    
        self.battery = MTTools.convertUint8(b: value[2]);
        self.beaconid = Int(value[3]) & 0x0F;
        self.setlev = Int(value[8] - 0x41);
    
        if (self.battery > 100) {
            self.battery = 100;
        }
        
        self.major = MTTools.convertUint16(hb: value[4], lb: value[5]);
        self.minor = MTTools.convertUint16(hb: value[6], lb: value[7]);
        
        self.mac = String(NSString(format: "%02X:%02X:%02X:%02X:%02X:%02X", value[9], value[10], value[11], value[12], value[13], value[14]));
    }
    
    private class func CBUUIDToByte(uuid: CBUUID) -> [UInt8]{
        var uuid_byte: [UInt8] = [UInt8](repeating: 0, count: uuid.data.count);
        
        uuid.data.copyBytes(to: &uuid_byte, count: uuid_byte.count);
        
        for i in 0..<(uuid_byte.count/2) {
            let tmp = uuid_byte[i];
            uuid_byte[i] = uuid_byte[uuid_byte.count-1-i];
            uuid_byte[uuid_byte.count-1-i] = tmp;
        }
        
        return uuid_byte;
    }
}

// 设备类型
public enum MTBLEDevice_MTBLEDEVICETYPE{
    case BLE
    case MTBLE
    case MTBeacon3
    case MTBeacon4
    case MTWX
}
